<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Three.js dancing Tree (for Xmas)</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="https://use.typekit.net/bji5ovt.css">
		<link rel="stylesheet" href="./style.css">

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/three.js"></script>
	</head>
	<body>
		<!-- partial:index.partial.html -->
		<canvas class="webgl"></canvas>
		<iframe src="xh.html"></iframe>
		 <h1><small>Christmas greetings </small> from <small>Xiao Zhang </small> top:圣诞节快乐</h1> 
		<h1><small></small> <small></small> </h1>
		<button id="play-music" type="button">Play music</button>

		<script type="x-shader/x-vertex" id="vertexShader">
			uniform float uTime;
uniform float uSize;
attribute float aScale;
attribute vec3 aColor;
attribute float phi;
attribute float random;
//attribute float random1;
varying vec2 vUv;
varying vec3 vColor;

void main() {
  float angle = phi;
  angle += uTime * random;
  angle = mod(angle, 39.3);
  float radius = 0.065 * angle;
  float rand = (random - 0.5) * 0.05 * pow(angle, .75);
  vec3 myOffset =
      vec3(radius * cos(angle) + rand,
           2.9 - 2.7 * radius + rand +
               0.1 * (random - .5) * pow(angle, .25) * sin(2.0 * uTime),
           radius * sin(angle) + rand);
  vec3 myPosition = myOffset;
  vec4 modelPosition = modelMatrix * vec4(myPosition, 1.0);

  vec4 viewPosition = viewMatrix * modelPosition;
  viewPosition.xyz += position * aScale * uSize;
  gl_Position = projectionMatrix * viewPosition;

  vColor = aColor;
  vUv = uv;
}
</script>

		<script type="x-shader/x-fragment" id="fragmentShader">
			varying vec3 vColor;
varying vec2 vUv;

void main() {
  vec2 uv = vUv;
  vec3 color = vColor;
  float strength = distance(uv, vec2(0.5));
  strength *= 2.0;
  strength = 1.0 - strength;
  gl_FragColor = vec4(strength * color, 1.0);
}
</script>

		<script type="x-shader/x-vertex" id="vertexShaderExt">
			#define M_PI 3.1415926535897932384626433832795
varying float vColorMix;
varying vec2 vUv;
uniform float uTime;

vec3 mod289(vec3 x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 mod289(vec4 x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x) {
     return mod289(((x*34.0)+1.0)*x);
}

vec4 taylorInvSqrt(vec4 r)
{
  return 1.79284291400159 - 0.85373472095314 * r;
}

float snoise(vec3 v)
  {
  const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
  const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
  vec3 i  = floor(v + dot(v, C.yyy) );
  vec3 x0 =   v - i + dot(i, C.xxx) ;

// Other corners
  vec3 g = step(x0.yzx, x0.xyz);
  vec3 l = 1.0 - g;
  vec3 i1 = min( g.xyz, l.zxy );
  vec3 i2 = max( g.xyz, l.zxy );

  //   x0 = x0 - 0.0 + 0.0 * C.xxx;
  //   x1 = x0 - i1  + 1.0 * C.xxx;
  //   x2 = x0 - i2  + 2.0 * C.xxx;
  //   x3 = x0 - 1.0 + 3.0 * C.xxx;
  vec3 x1 = x0 - i1 + C.xxx;
  vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
  vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y

// Permutations
  i = mod289(i);
  vec4 p = permute( permute( permute(
             i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
           + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
           + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));

// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
  float n_ = 0.142857142857; // 1.0/7.0
  vec3  ns = n_ * D.wyz - D.xzx;

  vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)

  vec4 x_ = floor(j * ns.z);
  vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)

  vec4 x = x_ *ns.x + ns.yyyy;
  vec4 y = y_ *ns.x + ns.yyyy;
  vec4 h = 1.0 - abs(x) - abs(y);

  vec4 b0 = vec4( x.xy, y.xy );
  vec4 b1 = vec4( x.zw, y.zw );

  //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
  //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
  vec4 s0 = floor(b0)*2.0 + 1.0;
  vec4 s1 = floor(b1)*2.0 + 1.0;
  vec4 sh = -step(h, vec4(0.0));

  vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
  vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;

  vec3 p0 = vec3(a0.xy,h.x);
  vec3 p1 = vec3(a0.zw,h.y);
  vec3 p2 = vec3(a1.xy,h.z);
  vec3 p3 = vec3(a1.zw,h.w);

//Normalise gradients
  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
  p0 *= norm.x;
  p1 *= norm.y;
  p2 *= norm.z;
  p3 *= norm.w;

// Mix final noise value
  vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
  m = m * m;
  return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
                                dot(p2,x2), dot(p3,x3) ) );
  }


mat3 rotation3dY(float angle) {
	float s = sin(angle);
	float c = cos(angle);

	return mat3(
		c, 0.0, -s,
		0.0, 1.0, 0.0,
		s, 0.0, c
	);
}

vec3 rotateY(vec3 v, float angle) {
	return rotation3dY(angle) * v;
}


void main() {
  float t = uTime * 0.1;
  float n = snoise(vec3(position.xy, t)*.2 + t);
  vec3 pos = position + n * 0.1;
  pos += 0.1*snoise(pos + t);
  gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
  vUv = uv;
  vColorMix = n;
}
</script>

		<script type="x-shader/x-fragment" id="fragmentShaderExt">
			varying float vColorMix;
varying vec2 vUv;

void main() {
  float n = vColorMix;
  vec2 uv = vUv;
  gl_FragColor = vec4(mix(vec3(uv, 1.0), vec3(0.0, 1.0, 1.0), 1.0 - n*n) , n * n * n );
}
</script>

		<script type="text/javascript">
			document.writeln(
				"<div class=\"snow\" style=\"height:1200px;  opacity: 0.3; position:fixed; left:0px; top:0px; right:0px; bottom:0px; pointer-events: none;z-index: 9999;\"><canvas width=\"1904\" height=\"913\" style=\"position: absolute;left: 0;top: 0;\"></canvas></div>"
				);

			$(function() {

				if (/MSIE 6|MSIE 7|MSIE 8/.test(navigator.userAgent)) {
					return
				}
				var container = document.querySelector(".snow");
				// IE9-10 pointer-events兼容
				if (/MSIE 9|MSIE 10/.test(navigator.userAgent)) {
					$(container).bind('click mousemove', function(evt) {
						this.style.display = 'none';
						var x = evt.pageX,
							y = evt.pageY
						if ($(document).scrollTop() > 0 || $(document).scrollTop() > 0) {
							x = x - $(document).scrollLeft() + 1
							y = y - $(document).scrollTop() + 1
						}
						evt.preventDefault();
						evt.stopPropagation();
						var under = document.elementFromPoint(x, y);
						var evtType = evt.type === 'click' ? 'click' : 'mouseenter'
						if (evt.type === 'click') {
							$(under)[0].click();
						} else {
							$(under).trigger('mouseenter');
						}
						$('body').css('cursor', 'default')
						this.style.display = '';
						return false;
					});
				}
				var containerWidth = $(container).width();
				var containerHeight = $(container).height();
				var particle;
				var camera;
				var scene;
				var renderer;
				var mouseX = 0;
				var mouseY = 0;
				var windowHalfX = window.innerWidth / 2;
				var windowHalfY = window.innerHeight / 2;
				var particles = [];
				var particleImages = [new Image(), new Image(), new Image(), new Image(), new Image()];
				// particleImages[0].src = "./images/snow1.png";
				// particleImages[1].src = "./images/snow2.png";
				// particleImages[2].src = "./images/snow3.png";
				// particleImages[3].src = "./images/snow4.png";
				// particleImages[4].src = "./images/snow5.png";
				particleImages[0].src = "img/151375665240370100.png";
				particleImages[1].src = "img/151375668550091372.png";
				particleImages[2].src = "img/151375669416355455.png";
				particleImages[3].src = "img/151375670204115466.png";
				particleImages[4].src = "img/151375671039447316.png";
				var snowNum = 300;

				function init() {
					camera = new THREE.PerspectiveCamera(75, containerWidth / containerHeight, 1, 10000);
					camera.position.z = 1000;
					scene = new THREE.Scene();
					scene.add(camera);
					renderer = new THREE.CanvasRenderer();
					renderer.setSize(containerWidth, containerHeight);
					for (var i = 0; i < snowNum; i++) {
						var material = new THREE.ParticleBasicMaterial({
							map: new THREE.Texture(particleImages[i % 5])
						});
						particle = new Particle3D(material);
						particle.position.x = Math.random() * 2000 - 1000;
						particle.position.y = Math.random() * 2000 - 1000;
						particle.position.z = Math.random() * 2000 - 1000;
						particle.scale.x = particle.scale.y = 1;
						scene.add(particle);
						particles.push(particle)
					}
					container.appendChild(renderer.domElement);
					document.addEventListener("mousemove", onDocumentMouseMove, false);
					document.addEventListener("touchstart", onDocumentTouchStart, false);
					document.addEventListener("touchmove", onDocumentTouchMove, false);
					setInterval(loop, 1000 / 50)
				}

				function onDocumentMouseMove(event) {
					mouseX = event.clientX - windowHalfX;
					mouseY = event.clientY - windowHalfY
				}

				function onDocumentTouchStart(event) {
					if (event.touches.length === 1) {
						event.preventDefault();
						mouseX = event.touches[0].pageX - windowHalfX;
						mouseY = event.touches[0].pageY - windowHalfY
					}
				}

				function onDocumentTouchMove(event) {
					if (event.touches.length === 1) {
						event.preventDefault();
						mouseX = event.touches[0].pageX - windowHalfX;
						mouseY = event.touches[0].pageY - windowHalfY
					}
				}

				function loop() {
					for (var i = 0; i < particles.length; i++) {
						var particle = particles[i];
						// 滚动到楼层模块，减少雪花 （自定义）
						if ($(window).scrollTop() < 1000) {
							particle.scale.x = particle.scale.y = 1;
						} else {
							if (i > particles.length / 5 * 3) {
								particle.scale.x = particle.scale.y = 0;
							} else {
								particle.scale.x = particle.scale.y = 0.8;
							}
						}
						particle.updatePhysics();
						with(particle.position) {
							if (y < -1000) {
								y += 2000
							}
							if (x > 1000) {
								x -= 2000
								if (x < -1000) {
									x += 2000
								}
							}
							if (z > 1000) {
								z -= 2000
							} else {
								if (z < -1000) {
									z += 2000
								}
							}
						}
					}
					camera.position.x += (mouseX - camera.position.x) * 0.005;
					camera.position.y += (-mouseY - camera.position.y) * 0.005;
					camera.lookAt(scene.position);
					renderer.render(scene, camera)
				}
				init()
			});
		</script>
		<!-- partial -->
		<script type="module" src="./script.js"></script>
		
	</body>
</html>
